<!DOCTYPE html>
<html>
  <head>
    <!-- 渲染属性 -->
    <!-- <script src="node_modules/three/build/three.js"></script> -->
    <script type="importmap">
      {
        "imports": {
          "three": "./node_modules/three/build/three.module.js",
          "three/addons/": "./node_modules/three/examples/jsm/"
        }
      }
    </script>
    <script type="module">
      import * as THREE from "three";

      // 引入dat.gui.js的一个类GUI
      import { GUI } from "three/addons/libs/lil-gui.module.min.js";
      // 浏览器控制台测试，是否引入成功
      console.log(THREE.Scene);
      console.log("完成");
      const width = window.innerWidth;
      const height = window.innerHeight;

      // 开始创建
      // 设置场景,坐标原点 0，0，0 中场景中央
      const scene = new THREE.Scene();

      // 点光源
      const pointLight = new THREE.PointLight(0xffffff, 1.0);
      scene.add(pointLight);

      pointLight.position.set(500, 500, 600);

      // 创建几何体中心坐标默认 0，0，0
      const geometry = new THREE.BoxGeometry(10, 20, 40); // 长方本。

      // 不管从哪个坐标轴旋转，都是从正方向向负方向看，逆时针旋转
      // geometry.rotateX(Math.PI / 4); //绕x轴旋转π/4，

      // 绕着Y轴旋转30度
      //  geometry.rotateY(Math.PI / 6);

      // 绕着Z轴旋转60度
      // geometry.rotateZ(Math.PI / 3);

      // 几何体旋转、缩放或平移之后，查看几何体顶点位置坐标的变化
      // BufferGeometry的旋转、缩放、平移等方法本质上就是改变顶点的位置坐标
      console.log("顶点位置数据", geometry.attributes.position);

      console.log("几何体", geometry);
      console.log("顶点位置数据", geometry.attributes.position);
      console.log("顶点索引数据", geometry.index);

      const material = new THREE.MeshLambertMaterial({
        color: 0x00ff00, //材质颜色
        side: THREE.DoubleSide, //不开双面，透明也看不见里面
        transparent: true, //开启透明
        opacity: 0.1, //设置透明度
        // wireframe: true,
      });

      const mesh = new THREE.Mesh(geometry, material);

      // 也可以用向量当坐标轴， 也是顶着向量方向，向原点看
      const axis = new THREE.Vector3(1, 1, 1); //向量axis
      //mesh.rotateOnAxis(axis, Math.PI / 8); //绕axis轴旋转π/8

      scene.add(mesh);

      //const geometry1 = geometry.clone();

      // 克隆了 mesh ，如果直接操作 mesh.geometry， mesh和mesh1会一起跟着变化，因为他们同用一个，如果移动旋转也一起，如果不同一起，就操作 Mesh 
      const mesh1 = mesh.clone();
      //const mesh1 = new THREE.Mesh(geometry1, material);
      //mesh1.geometry.translate(50, 0, 0);

      //mesh1.rotateX(Math.PI /2); //绕axis轴旋转π/8
      mesh1.translateX(20);


      scene.add(mesh1);

      // 现在已经把几何体放到场景中了，但还需要一只眼睛
      // 这是一个透视摄像机
      // 第一个参数，视角，视角越大，看的东西越多，相对就越小。
      // 第二个参数，宽高比例
      // 第三个参数，当被观测物体的边界小于这个值时，不可见。，如果，在10 的位置，物体高为 10，那么物体就顶天立地
      // 第四个参数，当被观测物体的边界大于这个值时，不可见。
      const camera = new THREE.PerspectiveCamera(50, width / height, 10, 1000);

      // 设置摄像机的位置
      camera.position.set(0, 0, 100);

      // 设置摄像机的观察点
      camera.lookAt(0, 0, 0);

      // 摄像机从 x -12 向 x 0 方向观察
      console.log(`camera`, camera.position);

      // 设置渲染器
      const renderer = new THREE.WebGLRenderer();

      renderer.setSize(width, height);

      // 设置空间背景颜色
      renderer.setClearColor(0xcccccc);
      renderer.render(scene, camera);

      document.body.appendChild(renderer.domElement);

      // 渲染方法
      function render() {
        // 用渲染器渲染
        renderer.render(scene, camera);

        // 重复渲染，需要查一下
        // 请求动画帧
        // requestAnimationFrame实现周期性循环执行
        // requestAnimationFrame默认每秒钟执行60次，但不一定能做到，要看代码的性能
        requestAnimationFrame(render); // 请求再次执行函数render, 放上面下面都行
      }

      // 执行渲染方法
      render();
    </script>
  </head>
  <body>
    GUI 控件
    <div id="monitor"></div>
  </body>
</html>
